/**
 * @author jouyang
 */
var RTQ_Options=function(){
    this.containerId = null;
    this.container = null;
    this.id = null;
    this.profile = {
		fixHeight:true,
		callback: {}
	};
    this.el = null;
    this.mainTicker = '';  // performance Id
    this.lastOption = null; 
	this.size = {width:0,height:0};
	this.callList = [];
	this.putList = [];
	this.strikeList=[];
	this.scribeParaList = [];
	this.splitLineIndex = [];
	this.selectedTabIndex = -1;
	this.lastPrice = -1; // the last price for the main ticker, it is used to compair the strike price.
	this.hasOptionData = false;// 
	this.minWidth = 800;
	this.selectedType = 1; // show all;
	this.selectedRange = 1; // show in and out of money ticker.
	this.selectedExpr = 0;
	this.selectedNumOfCols = 6;
	this._contains = {
		gLeft:null,
		gMiddle:null,
		gRight:null,
		hLeft:null,
		hMiddle:null,
        hRight:null,
		msg:null
	}  
    this.uiConfig = {
        settingPanel:null
    }
    this.exchDataList = [{
            txt: "Composite",
            val: ""
        }];
    this.typeDataList = [{
            txt: "Calls and Puts",
            val: 1
        }, {
            txt: "Calls",
            val: 2
        }, {
            txt: "Puts",
            val: 3
        }];
    this.rangeDataList = [{
            txt: "All",
            val: 1
        }, {
            txt: "In the Money",
            val: 2
        }, {
            txt: "Out of the Money",
            val: 3
        }, {
            txt: "At the Money",
            val: 4
        }];
	this.viewDataList = [{
            txt: "Last",
            val: "LastPrice",
			haschecked:true
        }, {
            txt: "Chg",
            val: "Chg",
			haschecked:true
        },{
            txt: "Bid",
            val: "BidPrice",
			haschecked:true
        }, {
            txt: "Ask",
            val: "AskPrice",
			haschecked:true
        }, {
            txt: "Vol",
            val: "Volume",
			haschecked:true
        },{
            txt: "Open Int",
            val: "OpenInt",
			haschecked:true
        }
	]	
    this.uiComponents = {
        callGrid : null,
        strikeGrid: null,
        putGrid: null,
		exprDDL:null,//expiration
        exchDDL:null,//exchange
        typeDDL:null,//type
        rangeDDL:null,//strategy
		viewGroup:null
    }
    this.callColumns = [];
    this.strikeColumns =[{
                header: "StrikeId",
                align:"center",
                dataIndex: 'strikeId',
                width: '0',
				hide:true
                },{
                header: "Strike",
                align:"center",
                dataIndex: 'strikePrice',
                width: '100%'
               }];
    this.putColumns = [];
	this.loaded = false;
};
RTQ_Options.prototype = {
    init:function(container, ticker, profile, componentId,uiConfig){
		this.size.width = profile.width, this.size.height = profile.height;
		if (profile){
			$.extend(this.profile,profile);
		}
        this.container = typeof(container)== "string"?$('#' + container):container;  // id or Jquery object.
        if(componentId!=this.id){          // pass the component path, not component id.
            this.ObjPath = componentId;
        }
        $.extend(this.uiConfig,uiConfig);
		if(profile&&profile.cols){
			for(var i=0;i<this.viewDataList.length;i++){
				if(profile.cols[this.viewDataList[i].val]== 0){
					this.viewDataList[i].haschecked = false;
					this.selectedNumOfCols--;
				}
			}
		}
		this._createUI();
		if (profile&&profile.ticker) {
            this.addOptions(profile.ticker,profile.type);  // type: 4 future option. 3 stock option
        }
    },
    _getGridConfig:function(columnData,defaultHeight,indexColKey,hContainer,resizeable){
        return {
            column: columnData,
            height: defaultHeight,
            htmlLayer: 'div',
            autoWidth: true,
            autoHeight: true,
            indexColKey: indexColKey,
            sortable: false,
            showYScrollbar: false,
			headerContainer:hContainer,
			cellResize:resizeable
        }
    },
    _getDropDownListConfig:function(w){
        return {riggerByClick: false,
            width: w,
            disable: true,
            actionAtInit: false
        }
    },
	_createGridCols:function(){
		this.putColumns = [], this.callColumns = [];
		var symbolColW = 25+75*0.4*(6-this.selectedNumOfCols)/6;
		var w = this.selectedNumOfCols >0?((99-symbolColW)/this.selectedNumOfCols).toFixed(2):56;
		this.putColumns.push({
                    align:"center",
                    header: "Puts",
                    dataIndex: 'symbol',
                    width: symbolColW+'%'
        });
		this.callColumns.push({
                    align:"center",
                    header: "Calls",
                    dataIndex: 'symbol',
                    width: symbolColW+'%'
        });
		for(var i=0;i<this.viewDataList.length;i++){
			if(this.viewDataList[i].haschecked){
				var item = {
                    align:"center",
                    header: this.viewDataList[i].txt,
                    dataIndex: this.viewDataList[i].val,
                    width: w+'%'
                }
				if(this.viewDataList[i].val=="Chg")item.className = "bold-cell";
				this.putColumns.push(item);
				this.callColumns.push(item)
			}
		}
		var eItem =[ {
                    header: "Strike",
                    align:"center",
                    dataIndex: 'strikePrice',
                    width: '0',
                    hide:true
            },{
                header: "StrikeId",
                align:"center",
                dataIndex: 'strikeId',
                width: '0',
                hide:true
        }]
		this.putColumns.push(eItem[0]),this.putColumns.push(eItem[1]);
        this.callColumns.concat(eItem[0]),this.callColumns.concat(eItem[1]);
	},
    _createUI:function(){
		var self = this,uiComps = this.uiComponents;
		this.el = $('<div class="rtq-options"><div class="bd"><div class="qs-option-toolbar">'+
				  '<div class="range"><h3>Strategy</h3></div><div class="type"><h3>Type</h3></div><div class="expr"><h3>Expiration</h3></div><div class="exchange"><h3>Exchange</h3></div>'+
                  '</div><div class="grid-header"><div class="wrap"><div class="h-left rtq-grid rtq-grid-auto" style="float:left;border:0"></div>'+
                  '<div class="h-mid rtq-grid rtq-grid-auto" style="float:left;border:0">'+
                  '</div><div class="h-right rtq-grid rtq-grid-auto" style="float:left;border:0"></div>'+
                  '</div></div><div class="grid-container"><div class="wrap clearfix"></div></div><div class="error-msg">No option available.</div></div></div>').appendTo(this.container);
		this._contains.msg = this.el.find(".error-msg").hide();	  
        //Strategy DDL
		uiComps.rangeDDL = new Util.DropDownList(this.el.find('.range')[0], function(t, v){
			if(self.selectedRange != v){
				self.selectedRange  = v;
				self.changeRange(v);
			}
            
        }, this.rangeDataList, this._getDropDownListConfig(110));
		//Type DDL
		uiComps.typeDDL = new Util.DropDownList(this.el.find('.type')[0], function(t, v){
			if(self.selectedType != v){
				self.selectedType = v;
                self.changeType(v);
			}
        }, this.typeDataList, this._getDropDownListConfig(110));
        //Expiration DDL
		uiComps.exprDDL = new Util.DropDownList(this.el.find('.expr')[0], function(t, v){
			if(self.selectedExpr != v){
				self.selectedExpr  = v;
				if(v == this.selectedTabIndex ){return;}
				self.bindGridData(v);
				self.unSubscribeOptions(self.selectedTabIndex);
				self.subscribeOptions(v);
				self.selectedTabIndex = v;
				self.mapGridData();  // get data from "gdata".
			}
        }, [], this._getDropDownListConfig(100));	
		//Exchange DDL
		uiComps.exchDDL = new Util.DropDownList(this.el.find('.exchange')[0], function(){
        }, this.exchDataList, this._getDropDownListConfig(80)); 
		
		this.el.find(".grid-container .wrap").html('<div class="g-left"></div><div class="g-mid"></div><div class="g-right"></div>');
		var ww = this.size.width;
		if(this.size.width < this.minWidth) ww = this.minWidth;
        this.headerContainer = this.el.find(".grid-header").css({width:ww});
        this.gridContainer = this.el.find(".grid-container").css({width:ww});
		this._setMinWidth(true);
		var w = 0.5*(ww-60);
		this._contains.gLeft= this.el.find(".g-left").css({width:w});
		this._contains.gMiddle= this.el.find(".g-mid").css({width:"60px"});
		this._contains.gRight= this.el.find(".g-right").css({width:w});
		this._contains.hLeft= this.el.find(".h-left").css({width:w});
        this._contains.hMiddle= this.el.find(".h-mid").css({width:"60px"});
        this._contains.hRight= this.el.find(".h-right").css({width:w});
        this._creatGrids();
        this._createSettingPn();
		if (this.profile.fixHeight) {
			this.dataScrollPN = new Util.ScrollPanel(this.gridContainer[0], {}, {
				onScroll: function(sl, st){//mboheader
					  if (typeof(self.headerContainer) != "undefined") {
						  self.headerContainer.scrollLeft(sl);
					  }
				}
			});
        }
    },
	_setMinWidth:function(needCalculteMinWidth){
		if(needCalculteMinWidth){
			var w = 800;
			if(this.selectedType==2 || this.selectedType == 3){
				w = 430;
			}
			this.minWidth = w*0.25+0.75*w*this.selectedNumOfCols/6;
		}
		this.headerContainer.find(".wrap").css({"min-Width":this.minWidth+"px"});
		this.gridContainer.find(".wrap").css({"min-Width":this.minWidth+"px"});
	},
    _createSettingPn: function(){
        var self = this,uiComps = this.uiComponents, settingPn = $(this.uiConfig.settingPanel);
        if(!settingPn) return;
        settingPn.html('<ul class="opt-settingpn" >' +         
            '<li class="subtitle">View</li><li class="view clearfix"></li></ul>');               
		uiComps.viewGroup = new Util.ButtonGroup(settingPn.find(".view"), this.viewDataList, {
			onClick: function(v,item){
				for (var i = 0; i < self.viewDataList.length; i++) {
					if(self.viewDataList[i].val == v){
						if(item.isSelected){
		                    self.viewDataList[i].haschecked = true;
							self.selectedNumOfCols++;
		                }else{
							self.viewDataList[i].haschecked = false;
							self.selectedNumOfCols--;
						}
						//self._createGridCols();
						self._changeCols();
						self._setMinWidth(true);
						self.bindGridData(self.selectedTabIndex);
						self.mapGridData();
						break;
					}
					
				}
			}
		},{type:'checkbox',vertical:true});
		for(var i=0;i<this.viewDataList.length;i++){
			if(this.viewDataList[i].haschecked){
				uiComps.viewGroup.btns[this.viewDataList[i].val].select();
			}
		}
    },
    _creatGrids:function(){
		this._createGridCols();
		this._contains.hLeft.html(""),this._contains.hMiddle.html(""),this._contains.hRight.html("");
		this._contains.gLeft.html(""),this._contains.gMiddle.html(""),this._contains.gRight.html("");
        this.uiComponents.callGrid = new Util.DataGrid(this._contains.gLeft, {}, this._getGridConfig(this.callColumns,400,"gkey",this._contains.hLeft,true),{});
        this.uiComponents.strikeGrid = new Util.DataGrid(this._contains.gMiddle, {}, this._getGridConfig(this.strikeColumns,400,"strikeId",this._contains.hMiddle,false),{});
        this.uiComponents.putGrid = new Util.DataGrid(this._contains.gRight, {}, this._getGridConfig(this.putColumns,400,"gkey",this._contains.hRight,true),{});
    },
	_changeCols:function(){
		this._createGridCols();
		this.uiComponents.callGrid.setColumnCfg(this.callColumns);
		this.uiComponents.putGrid.setColumnCfg(this.putColumns);
	},
    addOptions:function(ticker,type){  // add a stock as subject ticker of options
        if(this.mainTicker == ticker){ // add a same ticker.
            return;
        }
        var self = this;
        if(type==4){   // now only support one ticker for demo.
            if(typeof(QS_fOpt_SI)!= "undefine"){
                this.mainTicker = "66:@SI1N";
                var data = QS_fOpt_SI;  // option for "SI"
                if(gData["66:@SI1N"]&&gData["66:@SI1N"]["LastPrice"]){
                    this.lastPrice = gData["66:@SI1N"]["LastPrice"];  // get data from "gData".  
                }else{
                    this.lastPrice = -1; // set to default.
                    gData["66:@SI1N"]={};
                    gData["66:@SI1N"]["performanceId"]= "66:@SI1N";
                    gIdMap["66:@SI1N"]="66:@SI1N";
                } 
                push.proxy.batchSubscribe([{
                    gkey: "66:@SI1N",
                    paraList: [{
                        sourceType: "D",
                        serviceName: "66",
                        itemName: "3"+push.subSeparator+"@SI1N"+push.subSeparator+"-1"
                    }],
                    isSubscribeLevelII: false
                }])
                this.processFutureOptionData(data);
                if(typeof(this.afterAcceptTicker)== "function"){
                    this.afterAcceptTicker("@SI");
                }
            }
        }else{
            this.tValidation.checkTickers(ticker, function(o){
                self.tValidationCallback(o);
            });
        }
        
    },
    processFutureOptionData:function(data){
        this._contains.msg.hide();
        this.hasOptionData = true;
        var tabData=[],i=0;
        this.callList = [],this.putList = [],this.strikeList=[],this.scribeParaList=[];
        for(var o in data){
            tabData.push({txt:this._formateDate(o),val:i});
            this.callList[i] = [], this.putList[i] = [], this.strikeList[i] = [], this.scribeParaList[i] = [];
            var strikeMap = {}, pIndex = 0, cIndex = 0,sId = 1, cId = 1, pId = 1,tcode="66";
            this.strikeList[i] = [];
            for (var j = 0; j < data[o].length; j++) {
                this.strikeList[i].push({strikePrice:data[o][j]["strikePrice"],strikeId:j+1});
                this.callList[i].push( {
                        gkey: tcode + ":" + data[o][j]["C"],
                        symbol: data[o][j]["C"],
                        strikePrice: data[o][j]["strikePrice"],
                        strikeId: j+1
                    });
                this.putList[i].push({
                        gkey: tcode + ":" + data[o][j]["P"],
                        symbol: data[o][j]["P"],
                        strikePrice: data[o][j]["strikePrice"],
                        strikeId: j+1
                    });

                this.scribeParaList[i].push( {
                    gkey: tcode + ":" + data[o][j]["C"],
                    optionType: "C",
                    paraList: [{
                        sourceType: "D",
                        serviceName: tcode,
                        itemName: "4" +push.subSeparator+ data[o][j]["C"] + push.subSeparator+ "-1"
                    }],
                    isSubscribeLevelII: false
                });
                this.scribeParaList[i].push( {
                    gkey: tcode + ":" + data[o][j]["P"],
                    optionType: "P",
                    paraList: [{
                        sourceType: "D",
                        serviceName: tcode,
                        itemName: "4"+push.subSeparator+ data[o][j]["P"] + push.subSeparator+"-1"
                    }],
                    isSubscribeLevelII: false
                })
            }
            i++;
        }          
        if(this.selectedTabIndex>=0&&this.scribeParaList.length)this.unSubscribeOptions(this.selectedTabIndex); 
        this.uiComponents.exprDDL.rebindData(tabData);
        this.uiComponents.exprDDL.selectItemByValue(tabData[0]['val']);
        this.bindGridData(0);
        this.selectedTabIndex = 0;
        this.subscribeOptions(0);
        this.mapGridData();
        this._setDDLAble();
    },
    tValidationCallback:function(gList){
		if(typeof(this.hideLoading) == 'function'&&typeof(gList)!= 'undefined'&&gList.length==0){
            this.hideLoading();
        }
        if(!gList || !gList.length){// check failed.
            if(this.__winObj&&this.__winObj.searchEl){
               var gkey = gIdMap[this.mainTicker];
               if(gkey&&gData[gkey]){
                  this.__winObj.searchEl.find("#"+this.__winObj._autoBoxID).val(gData[gkey]["ticker"]);
               }
            }
        }else{
            var d = gData[gList[0]];
			if(this.mainTicker!=null||this.mainTicker!=""){ // unsubscribe the last main tikcer
				this.tValidation.unSubscribe([this.mainTicker]);
			}
            this.mainTicker = gData[gList[0]]["performanceId"];//d.exch+':'+d.ticker;    
            if (typeof(this.setTitle)=="function") {
                this.setTitle("Options:",gData[gList[0]]["ticker"]);
            }   
            if(gData[gList[0]]&&gData[gList[0]]["LastPrice"]){
				this.lastPrice = gData[gList[0]]["LastPrice"];  // get data from "gData".  
			}else{
				this.lastPrice = -1; // set to default.
			}   
            //var p = typeof(this.ObjPath)=="undefined"?"push.proxy.getOptions(" + this.id + ").optionsArrived":this.ObjPath+".optionsArrived";
            var self = this;
            var url = QS_PROTOCOL + "qt.morningstar.com/switchservice/getoptionchain.ashx?t=" + this.mainTicker + "&region=" + d.country + "&cb=?";
            $.getJSON(url,function(d){
                self.optionsArrived(d);
            });
            if(typeof(this.afterAcceptTicker)== "function"){
                this.afterAcceptTicker(gData[gList[0]]["ticker"]);
            }
        }
    },
    optionsArrived:function(data){  // when option chain arrive at browse.
        this.splitLineIndex = [];
        if(data&&data.Chain){
			this._contains.msg.hide();
			this.hasOptionData = true;
			var info = data.Chain;
			var dateList = info.Expirations;
			var detailList = info.Details;
			var tabData=[];
			for(var i=0;i<dateList.length;i++){
				tabData.push({txt:this._formateDate(dateList[i]),val:i});
			}			
			if(this.selectedTabIndex>=0&&this.scribeParaList.length)this.unSubscribeOptions(this.selectedTabIndex); 
			this.uiComponents.exprDDL.rebindData(tabData);
			this.uiComponents.exprDDL.selectItemByValue(tabData[0]['val']);
			this.callList = [],this.putList = [],this.strikeList=[],this.scribeParaList=[];
			var tcode="";dtType= (typeof(QS_Permission)!="undefined"&&QS_Permission.getSubcodes(2,3,"","R").length)?"R":"D";  // real-time or delayed.
			for(var i=0;i<detailList.length;i++){
				this.callList[i]=[],this.putList[i]=[],this.strikeList[i]=[],this.scribeParaList[i]=[];
				var strikeMap={},pIndex=0,cIndex=0,sId=1,cId=1,pId=1;
				this.strikeList[i]=[];
				for(var j=0;j<detailList[i].length;j++){
					var t = detailList[i][j].Info, feed = detailList[i][j].Feed;
					tcode = feed[1]=="3"?"126":feed[1];
					if(t[3]== "C"){
						this.callList[i][cIndex]={gkey:tcode + ":" + feed[0],symbol:t[0],strikePrice:t[4],strikeId:cId++};
						cIndex++;
					}else if(t[3]=="P"){
						this.putList[i][pIndex]={gkey:tcode + ":" + feed[0],symbol:t[0],strikePrice:t[4],strikeId:pId++};
						pIndex++;
					}
					this.scribeParaList[i][j]= {gkey: tcode + ":" + feed[0],optionType:t[3],
	                    paraList: [{
	                        sourceType: dtType,
	                        serviceName: tcode,
	                        itemName: "2"+ push.subSeparator+ feed[0] + push.subSeparator+(dtType=="D"?"-1":"0")  // subcode:R:0, D:-1
	                    }],isSubscribeLevelII: false}
					if(typeof(strikeMap[t[4]])=="undefined"){ // the first strik price.
					    strikeMap[t[4]]= t[3];
						this.strikeList[i].push({strikePrice:t[4],strikeId:sId++});
					}else{
						if(strikeMap[t[4]] != t[3]){  // same strik price and not type(call or put).
							delete strikeMap[t[4]];
						}
					}
				}
				this.strikeList[i].sort(function(a,b){
	                return parseFloat(a.strikePrice)>parseFloat(b.strikePrice)?1:-1
	            });
	            this.callList[i].sort(function(a,b){
	                return parseFloat(a.strikePrice)>parseFloat(b.strikePrice)?1:-1
	            });
	            this.putList[i].sort(function(a,b){
	                return parseFloat(a.strikePrice)>parseFloat(b.strikePrice)?1:-1
	            });
				/*var index = 0;
				for(var o in strikeMap){
                    this.strikeList[i][index] = {
						strikePrice: o
					};
					index++;
                }*/
			}
			// sort the list.
            this.bindGridData(0);
		    this.selectedTabIndex = 0;
			this.subscribeOptions(0);
			this.mapGridData();
			this._setDDLAble();
		}else{  // no option tickers clear data.
			this.hasOptionData = false;
			if(this.selectedTabIndex>=0&&this.scribeParaList.length)this.unSubscribeOptions(this.selectedTabIndex);
			this.callList = [],this.putList = [],this.strikeList=[],this.scribeParaList=[],this.selectedTabIndex=-1;
			this.uiComponents.exprDDL.rebindData([]);
			this.uiComponents.callGrid.empty();
            this.uiComponents.putGrid.empty();
            this.uiComponents.strikeGrid.empty();
			this._contains.msg.show();
		}
    },
	bindGridData:function(index){
		if(typeof(this.showLoading)=="function")this.showLoading(true);
        this.uiComponents.callGrid.reBindData(this.callList[index]);
        this.uiComponents.putGrid.reBindData(this.putList[index]);
        this.uiComponents.strikeGrid.reBindData(this.strikeList[index]);
		this._initInTheMoneyBg(index);
        this.changeOutSize(this.size.width,this.size.height);
		if(typeof(this.hideLoading)=="function")this.hideLoading();
	},
	_setDDLAble:function(){
		if(this.uiComponents.exchDDL) this.uiComponents.exchDDL.setDisable(false);
		if(this.uiComponents.typeDDL) this.uiComponents.typeDDL.setDisable(false);
		if(this.uiComponents.rangeDDL) this.uiComponents.rangeDDL.setDisable(false);
		if(this.uiComponents.exprDDL) this.uiComponents.exprDDL.setDisable(false);
	},
	_initInTheMoneyBg:function(index){
		if(this.hasOptionData&&this.lastPrice>0){ // has an vaild last price
		    var hasSplit = false;
            for(var i=0;i<this.strikeList[index].length;i++){
				var sPrice = this.strikeList[index][i]["strikePrice"];
                if(sPrice>this.lastPrice){
					if(i>=this.putList[index].length)continue;
                    this.uiComponents.putGrid.rows[this.putList[index][i].gkey].el.addClass("inmoney-row");
					if (!hasSplit) {
						hasSplit = true;
						this.splitLineIndex[index] = i;
					}
                }else if(sPrice<this.lastPrice){
					if(i>=this.callList[index].length)continue;
                    this.uiComponents.callGrid.rows[this.callList[index][i].gkey].el.addClass("inmoney-row");
                }
            }
        }
	},
	_changeInTheMoneyRange:function(index){ // when last price change, change the in the money range.
		if(this.hasOptionData&&this.strikeList&&this.strikeList.length>index&&this.strikeList[index]&& this.splitLineIndex[index]!=null){
			var oldIndex = this.splitLineIndex[index], newIndex = this.splitLineIndex[index];
			if(oldIndex>0&&this.strikeList[index][oldIndex-1]["strikePrice"]>this.lastPrice){// split line upforwad
			    newIndex = oldIndex-1;
				for(var i = oldIndex-2;i>=0;i--){
					if(this.strikeList[index][i]["strikePrice"]<=this.lastPrice){
						newIndex = i+1;
						break;
					}
				}
			}
			if((oldIndex+1)<this.strikeList[index].length&&this.strikeList[index][oldIndex+1]["strikePrice"]<=this.lastPrice){// split line downforwad.
				newIndex = oldIndex+1;
				for(var i = oldIndex+2;i<this.strikeList[index].length;i++){
                    if(this.strikeList[index][i]["strikePrice"]>this.lastPrice){
                        newIndex = i-1;
                        break;
                    }
                }
			}
			if(newIndex<oldIndex){  // change the range.
				for(var i= newIndex;i<oldIndex;i++){
					this.uiComponents.callGrid.rows[this.callList[index][i].gkey].el.removeClass("inmoney-row");
					this.uiComponents.putGrid.rows[this.putList[index][i].gkey].el.addClass("inmoney-row");
				}
			}else{
				for(var i= oldIndex;i<newIndex;i++){
                    this.uiComponents.putGrid.rows[this.putList[index][i].gkey].el.removeClass("inmoney-row");
                    this.uiComponents.callGrid.rows[this.callList[index][i].gkey].el.addClass("inmoney-row");
                }
			}
		}
	},
	_formateDate: function(odate){ // YYYY-mm-DD
        var t = odate.split("-");
        var dt = new Date(parseInt(t[0], 10), parseInt(t[1], 10) - 1, parseInt(t[2], 10) - 1);
        var dtFormat = DTFormat.Mo[dt.getMonth()] + ' ' + dt.getDate() + ', ' + dt.getFullYear();
        return dtFormat;
    },
	subscribeOptions:function(index){
		if(this.scribeParaList&&this.scribeParaList.length>index)push.proxy.batchSubscribe(this.scribeParaList[index]);
	},
	unSubscribeOptions:function(index){
		if(this.scribeParaList&&this.scribeParaList.length>index)push.proxy.batchUnsubscribe(this.scribeParaList[index]);
	},
	updateData:function(gkey,fields){
		if(gData[gkey]&&gData[gkey]["performanceId"]==this.mainTicker){ // update main ticker
			for(var o in fields){
				if(o=="LastPrice"){
					if(this.lastPrice<0){  // the first price arrived
					   this.lastPrice = gData[gkey]["LastPrice"];
					   this._initInTheMoneyBg(this.selectedTabIndex);
					}else {
						this.lastPrice = gData[gkey]["LastPrice"];
						this._changeInTheMoneyRange(this.selectedTabIndex); // change the range of 
					}	
					break;
				};		
			}
		}else{
			if(gData[gkey]&&gData[gkey]["optionType"]){
				var otype = gData[gkey]["optionType"];
				var grid = otype=="C"?this.uiComponents.callGrid:this.uiComponents.putGrid;
				if(!grid.DOMMap[gkey])return //this ticker not exist in grid 
				var stPrice = grid.rows[gkey]["data"]["strikePrice"];
				if(this.selectedRange == 2){  // only update in the money tickers
					if(otype=="C"&&stPrice>=this.lastPrice)return ;
					else if(otype=="P"&&stPrice<this.lastPrice)return
				}else if(this.selectedRange == 3){ // only update out of moneny data.
					if(otype=="C"&&stPrice<this.lastPrice)return ;
                    else if(otype=="P"&&stPrice>=this.lastPrice)return
				}			   
				var type, gValue,el,value;
				for(var o in fields){
					type = fields[o].dataType;
					gValue = gData[gkey][o];
					el = grid.DOMMap[gkey][o];
					if(!el) continue;
					if(type=="f"){
						value = isNaN(gValue)?"--":Math.abs(gValue)>=0.01?gValue.toFixed(2):gValue;
					}else{
						value = gValue;
					}
					if(el){
						el.innerHTML = value;
					}
					if(o=="LastPrice"){ // falsh colorful background.
						flash(el, gValue, fields[o].oldValue);
					}else if(o=="Chg"){// change color of font according the value.
						//el.style.color = gValue>=0?QS_Style.greenFontColor : QS_Style.redFontColor;
						flashWithDirectional(el, gValue, fields[o].oldValue,gValue>=0);
					}else if(o=="AskPrice"||o=="BidPrice"||o=="OpenInt"){// flash gray background
						flash(el, null, null);
					}
				}
			}
		}
	},
	mapGridData:function(){  // get data from "gData" to fill the grid cells.
		if(this.mainTicker!=""&&gData[gIdMap[this.mainTicker]]&&gData[gIdMap[this.mainTicker]]["LastPrice"]){
			this.lastPrice = gData[gIdMap[this.mainTicker]]["LastPrice"];
		}
		this._fillDataToGrid(this.uiComponents.callGrid,"C");
		this._fillDataToGrid(this.uiComponents.putGrid,"P");
	},
	_fillDataToGrid:function(grid,type){
		var el,value, op="all",isHide=false;
		if(this.selectedRange==2){ // in the money
			op= type=="C"?"<":">";
		}else if(this.selectedRange==3){ //out of money.
			op= type=="C"?">":"<";
		}else if(this.selectedRange==4){ // at the money
			op= "=";
		}
		isHide = ((type=="C"&&this.selectedType==2)||(type=="P"&&this.selectedType==3));
		for(var key in grid.rows){
            if(!gData[key]) continue;
			var da = grid.rows[key].data["strikePrice"],dId = grid.rows[key].data["strikeId"];
			if(op=="<"&&da>=this.lastPrice){ // 
				this.clearRowdata(grid.rows[key],dId,isHide);
			}else if(op==">"&&da<=this.lastPrice){
				this.clearRowdata(grid.rows[key],dId,isHide);
			}else if(op=="="&&da!=this.lastPrice){
				this.clearRowdata(grid.rows[key],dId,isHide);
			}else{
				for(var o in grid.rows[key].cells){
	                if(o=="Volume"||o=="OpenInt")value = isNaN(gData[key][o])?"":parseInt(gData[key][o],10).toFixed(0);
	                else if(o=="symbol"||o=="strikePrice"){ 
	                    continue;
	                }else value = isNaN(gData[key][o])?"": parseFloat(gData[key][o]).toFixed(2);
	                grid.DOMMap[key][o].innerHTML = value;
	                if(o=="Chg"&&value!=""){
	                    flashWithDirectional(grid.DOMMap[key][o], value, null,value>=0);
	                }
	            }
			}    
        }
	},
	clearRowdata:function(row,strikeId,isHide){
		for(var o in row.cells){
			if(o=="symbol"){
				row.cells[o].innerDom.innerHTML = "";
			}
		}
		if(isHide){
			row.el.hide();
			this.uiComponents.strikeGrid.rows[strikeId].el.hide();
		}else{
			row.el.show();
			this.uiComponents.strikeGrid.rows[strikeId].el.show();
		}
	},
	changeOutSize:function(width,height){
		if (this.profile.fixHeight){
			var realW=width<this.minWidth?this.minWidth:width;//window's width
			var iw = (this.selectedType==1?0.5:1)*(realW-60);// the grid real width, there are two grids in options, selectType equals one means both two grids are shown, so, the width of each grid are half of the whole width
			var rw = this.selectedType==3||this.selectedType==1?this._contains.gRight.width():this._contains.gLeft.width();
			var aw = iw>rw?rw:iw;
			if(this.selectedType==2||this.selectedType==1){ //all or calls.
				this._contains.gLeft.css({width:aw-18}); 
				this._contains.hLeft.css({width:aw-18});
			}
			if(this.selectedType==1||this.selectedType==3){ // all or puts.
				this._contains.gRight.css({width:aw-18});  // reduce the width of grid to aviod the right grid wrap.
				this._contains.hRight.css({width:aw-18});
			}
			this.dataScrollPN.reSize(width, height-54);
			var self = this;
			self.size.width = width;
			self.size.height = height;
			self.el.css({width:self.size.width});
			setTimeout(function(){
				var dx = 60;
				if(!self.dataScrollPN.scrollbarX.isShow&&self.dataScrollPN.scrollbarY.isShow){
					dx = 76;
				}
				var ww = width;
				if(ww<self.minWidth){
					ww = self.minWidth;
				}
				var w = 0.5*(ww-dx), lw,rw;
				if(self.selectedType==2){// show call 
					lw = 2*w,rw=0;
				}else if(self.selectedType==3){
					rw = 2*w,lw=0;
				}else{
					lw = rw =w;
				}	
				self.headerContainer.css({width:width});
				self.gridContainer.css({width:width});
				self._contains.gLeft.css({width:lw});
				self._contains.gMiddle.css({width:"60px"});
				self._contains.gRight.css({width:rw});
				self._contains.hLeft.css({width:lw});
				self._contains.hMiddle.css({width:"60px"});
				self._contains.hRight.css({width:rw});
			},100)
	    }	
		else{
			this.onHeightChange(this.el.outerHeight(true));
		}
	},
    onHeightChange:function(height){
        if (!this.loaded) {
            this.loaded = true;
            this.lastCallbackHeight = height;
            if (typeof this.profile.callback.onLoad == 'function') {
                this.profile.callback.onLoad({
                    component: 'option',
                    height: height
                });
            }
        }else {
            if (this.lastCallbackHeight != height) {
                this.lastCallbackHeight = height;
                if (typeof this.profile.callback.onHeightChange == 'function') {
                    this.profile.callback.onHeightChange({
                        component: 'option',
                        height: this.lastCallbackHeight
                    });
                }
            }
        }
    },

	changeType:function(v){
		var con = this._contains, hCon=this.headerContainer.find(".wrap"),gCon = this.gridContainer.find(".wrap");
		if(v==1){ // show all
			con.gMiddle.insertAfter(con.gLeft);
            con.hMiddle.insertAfter(con.hLeft);
		    con.gLeft.show();
		    con.gRight.show();	
			con.hLeft.show();
            con.hRight.show();	
		}else if(v==2){//only show call,		
			con.gLeft.show();
            con.gRight.hide();
			con.hLeft.show();
            con.hRight.hide();
			con.gMiddle.insertBefore(con.gLeft);
			con.hMiddle.insertBefore(con.hLeft);
		}else if(v==3){//only show put,		
		    con.gLeft.hide();
            con.gRight.show();
			con.hLeft.hide();
            con.hRight.show();
		}
		this._setMinWidth(true);
		if(this.selectedRange == 2 || this.selectedRange==3){
            this.mapGridData();
        }
		this.changeOutSize(this.size.width,this.size.height);
	},
	changeRange:function(v){
		this.bindGridData(this.selectedTabIndex);
		this.mapGridData();	
	},
	acceptTicker: function(Ticker){
        this.addOptions(Ticker);
    },
	autoCPCallback: function(o){
        this.addOptions(o);
    },
	saveConfig: function(){ // save the main ticker and columns of view.
		var cols = {};
		for(var i=0;i<this.viewDataList.length;i++){   // save the columns of view.
			cols[this.viewDataList[i].val] = this.viewDataList[i].haschecked?1:0;
		}
        return {
            ticker: this.mainTicker,
            title: this.getTitle(),
			cols:cols
        }
    },
	clear:function(){
		if(this.mainTicker)this.tValidation.unSubscribe([this.mainTicker]);
		this.unSubscribeOptions(this.selectedTabIndex);
	}
}
